home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
install
/
package-.1
/
package-
/
package-0.1
/
bin
/
pkg
< prev
Wrap
Text File
|
1993-04-01
|
14KB
|
673 lines
#!/bin/sh
#
# $Id: pkg,v 1.2 1993/02/19 13:00:48 mike Exp $
# Save the name of the script for later. That way I don't have to hardcode
# the name all over before I've decided what it will finally be :-)
progname=`basename $0`
# If the default target directory isn't set it defaults to the current
# directory.
DEF_TARGET=.
# The default path to search is somewhat arbitrary...
PKGPATH=.:/packages:/usr/packages:/usr/local/packages:/var/packages
# A list of possible file system types (used when trying to mount disks).
FSTYPES="msdos ext2 xiafs minix ext"
# If a defaults file exists parse it into shell syntax and source it. We
# don't keep defaults files in shell syntax to avoid tempting people to
# source them directly. This could be funny...
if [ -r /etc/default/package ]; then
awk '
/^#/ { next; }
/^[ \t]*$/ { next; }
{ printf "%s=%s ; export %s\n", $1, $2, $1 }
' /etc/default/package > /tmp/pkg$$ && . /tmp/pkg$$
rm -f /tmp/pkg$$
fi
target="$DEF_TARGET"
if [ "$target" = "/" ]; then
target=
fi
# Compression commands. You may be using compress, freeze, gzip...
# These commands should work in pipelines...
#COMP=compress
COMP=gzip
#UNCOMP=uncompress
UNCOMP=gunzip
ZCAT=zcat
# If this is a traditional old Bourne shell we can probably use backslash
# escapes regardless. If this is Bash we may need the -e option to the
# built in echo. This seems to make Bash incompatible? Is this POSIX
# behaviour? Is it a compile time configuration option in Bash? I dunno...
if [ -n "$BASH_VERSION" ]; then
use_escapes="-e"
else
use_escapes=""
fi
function usage()
{
cat << !!MIKE_WANTS_CHOCCY!!
Options:
-n
Does not actually make changes to the target directory
during a rebuild.
-a|--add <package>
Adds the package in the specified directory to the list
of packages which are installed in the current target
directory.
--doc|--readme <package>
Browse the documentation for the given package.
-i|--info <regular expression>
Give information about any files installed in the current
target directory which match the given regular expression.
--install <archive> | <device>
Extract from the given archive and add the packages found
to the current target directory. If the given name is a
device then it is mounted and all archives found on it are
extracted into the current directory.
-l|--list
List the packages intalled in the current target directory.
-r|--rebuild
Rebuild the current target directory by merging the map
files of the installed packages and applying the resulting
map instructions.
-r|--remove <package>
Remove the package in the specified directory from the
list of packages which are installed in the current target
directory.
-t|--target <directory>
Sets the current directory for installation.
!!MIKE_WANTS_CHOCCY!!
}
function read_docs()
{
HERE=`pwd`
TOPDIR=$1/doc
if [ ! -d $1/doc ]; then
echo "No documentation found in $1"
return
fi
cd $1/doc
echo
echo "Available documents:"
echo
ls -C
echo
doc=
while [ "$doc" != "quit" ]
do
echo -n "Enter document name (type quit when done): "
read doc
if [ -z "$doc" ]; then
echo
echo "Available documents:"
echo
ls -C
echo
elif [ -d "$doc" ]; then
case "$doc" in
..*|./..*)
if [ "`pwd`" = $TOPDIR ]; then
echo
echo "Already in the top directory"
echo
doc=
else
cd $doc
echo
echo "Available documents:"
echo
ls -C
echo
fi
;;
*)
cd $doc
echo
echo "Document directory $doc contains the following:"
echo
ls -C
echo
;;
esac
elif [ -f "$doc" ]; then
echo
${PAGER:-less} $doc
echo
elif [ "$doc" != "quit" ]; then
echo
echo "No such document or directory: $doc"
echo
fi
done
cd $HERE
}
function location()
{
# If we have been given a path list we'll use it.
if [ "$2" = "" ]; then
path=$PKGPATH
else
path=$2
fi
echo $path | tr ':' '\n' | while read p
do
if [ -n "$p" -a "$p" != "." ]; then
it=`ls -1dr $p/$1 $p/$1-* 2> /dev/null | head -1`
else
it=`ls -1dr $1 $1-* 2> /dev/null | head -1`
fi
if [ -n "$it" ]; then
echo $it
exit
fi
# if [ -e $p/$1 ]; then
# if [ "$p" != "." ]; then
# echo $p/$1
# else
# echo $1
# fi
# exit
# fi
done
}
function gen_list()
{
if [ ! -r $1/PKG/map -a -z "$quiet" ]; then
echo $use_escapes "(no map) \c" 1>&2
return
fi
awk '
BEGIN { def_ver = "0" }
/^#/ { done=1 }
/^[ \t]*$/ { done=1 }
$1 == "VERSION" {
def_ver = $2
done = 1
}
done == 0 {
if ($2 ~ /[*?]/) {
op = $1
dest = $3
if (NF == 4)
ver = $4
else
ver = def_ver
cmd = sprintf("ls -1 %s/%s 2> /dev/null; exit 0", basedir, $2)
while (cmd | getline) {
printf "%s %s %s/%s %s\n", op, $0, dest, substr($0, 1+match($0, "/[^/]*$")), ver
}
} else {
if (NF == 4)
ver = $4
else
ver = def_ver
printf "%s %s/%s %s %s\n", $1, basedir, $2, $3, ver
}
}
{ done=0 }
' basedir=$1 $1/PKG/map
}
function do_install()
{
target=$1
$ZCAT $target/.map | awk '
BEGIN {
last_path = ""
}
$3 != last_path {
if (match($3, "^/.*") == 1)
printf "%s %s %s\n", $1, $2, $3
else
printf "%s %s %s/%s\n", $1, $2, target, $3
last_path = $3
}
' target=$target | /usr/lib/pkg/pipe-inst $no_action
}
function do_purge()
{
dir=$1
$ZCAT $dir/.map | awk '
BEGIN {
last_path = ""
}
$3 == last_path {
print $2
last_path = $3
}
' target=$dir | /usr/lib/pkg/pipe-rm $no_action
}
function mount_disk()
{
for i in $FSTYPES
do
mount -t $i $1 $2 2> /dev/null
if [ $? -eq 0 ]; then
ok=yes
break
fi
done
if [ -z "$ok" ]; then
echo "error: unable to mount disk." 1>&2
return 1
else
return 0
fi
}
function add_package()
{
if [ -f $target/.installed ]; then
curr_pkg=`egrep "/$1(-[-0123456789.]*)?$" $target/.installed`
else
curr_pkg=
fi
if [ -n "$curr_pkg" ]; then
if [ -z "$quiet" ]; then
echo $1 is already installed here from $curr_pkg.
fi
else
locn=`location $1`
[ -n "$locn" ] && case "$locn" in
/*)
echo $locn >> $target/.installed \
&& [ -z "$quiet" ] && echo "Added $1 to $target."
;;
*)
echo `pwd`/$locn >> $target/.installed \
&& [ -z "$quiet" ] && echo "Added $1 to $target"
;;
esac
fi
}
function remove_package()
{
if [ -z "$quiet" ]; then
echo "Remove from $target:"
egrep "$1" $target/.installed
fi
mv $target/.installed $target/.installed.old
egrep -v "/$1(-[-0123456789.]*)?$" $target/.installed.old > $target/.installed
rm -f $target/.installed.old
}
function install_package()
{
# Note what we have already.
ls -1 > /tmp/pkgA$$
# If we are given a block device we try and mount it, extract any
# packages we find on it and then unmount it again. Otherwise we
# assume we were just given a package name.
if [ -b "$1" ]; then
rm -f /tmp/pkgm$$
mkdir /tmp/pkgm$$
if mount_disk $1 /tmp/pkgm$$; then
for i in /tmp/pkgm$$/*
do
[ -z "$quiet" ] && echo "Extracting "`basename $i`
tar xfzpsS "$i"
done
umount /tmp/pkgm$$
rmdir /tmp/pkgm$$
else
rm /tmp/pkgA$$
rmdir /tmp/pkgm$$
exit 1
fi
else
[ -z "$quiet" ] && echo "Extracting $1"
tar xfzpsS "$1"
fi
# Find what we have now.
ls -1 > /tmp/pkgB$$
# Add anything that was not here originally.
comm -13 /tmp/pkgA$$ /tmp/pkgB$$ | while read i
do
add_package "$i"
done
rm -f /tmp/pkgA$$ /tmp/pkgB$$
}
# If we haven't any arguments just display the usage message.
if [ $# -eq 0 ]; then
usage
exit 1
fi
no_action=
quiet=
while [ $# -ne 0 ]
do
case "$1" in
-n)
no_action=-n
shift
;;
-q|--quiet|--quite)
# Yeah, quite is a mispelling but we can guess
# what they mean.
quiet=yes
shift
;;
-t|--target)
if [ -z "$2" ]; then
echo "$1 requires an argument"
exit 1
fi
target=$2
if [ "$target" = "/" ]; then
target=
fi
shift; shift
;;
--install|--extract)
if [ -z "$2" ]; then
echo "$1 requires an argument" 1>&2
exit 1
fi
shift
done=
while [ -n "$1" -a -z "$done" ]
do
case "$1" in
-*) done=yes
;;
*)
install_package "$1"
shift
;;
esac
done
;;
-a|--add)
if [ -z "$2" ]; then
echo "$1 requires an argument" 1>&2
exit 1
fi
shift
done=
while [ -n "$1" -a -z "$done" ]
do
case "$1" in
-*) done=yes
;;
*) add_package "$1"
shift
;;
esac
done
;;
--purge)
echo
echo "This operation removes files from the actual package directories which"
echo "have been superceeded by later versions and are no longer required on"
echo "your system."
echo
ans=
while [ "$ans" != "y" -a "$ans" != "Y" -a "$ans" != "n" -a "$ans" != "N" ]
do
echo $use_escapes "Are you sure you want to do this? (y/n): \c"
read ans
done
if [ "$ans" = "y" -o "$ans" = "Y" ]; then
do_purge $target
fi
shift
;;
--conf*)
if [ -z "$2" ]; then
echo "$1 requires an argument" 1>&2
exit 1
fi
if [ -f $target/.installed ]; then
locn=`grep "$2" $target/.installed`
else
locn=
fi
if [ -z "$locn" ]; then
locn=`location $2`
[ -n "$locn" ] && case "$locn" in
/*)
;;
*)
locn=`pwd`/$locn
;;
esac
fi
if [ -n "$locn" ]; then
if [ -x $locn/PKG/configure ]; then
(cd $locn ; PKG/configure)
else
echo "No configuration is necessary for $2"
fi
else
echo "can't find package $2"
fi
shift; shift
;;
--doc*|--read*)
if [ -z "$2" ]; then
echo "$1 requires an argument" 1>&2
exit 1
fi
if [ -f $target/.installed ]; then
locn=`grep "$2" $target/.installed`
else
locn=
fi
if [ -z "$locn" ]; then
locn=`location $2`
[ -n "$locn" ] && case "$locn" in
/*)
;;
*)
locn=`pwd`/$locn
;;
esac
fi
if [ -n "$locn" ]; then
read_docs $locn
else
echo "can't find package $2"
fi
shift; shift
;;
-d|--del*|--rm|--rem*)
if [ -z "$2" ]; then
echo "$2 requires an argument" 1>&2
exit 1
fi
shift
done=
while [ -n "$1" -a -z "$done" ]
do
case "$1" in
-*) done=yes
;;
*) remove_package "$1"
shift
;;
esac
done
;;
-l|--list|--ls)
if [ ! -s $target/.installed ]; then
if [ -z "$target" ]; then
echo "Nothing installed in /."
else
echo "Nothing installed in $target."
fi
else
if [ -z "$target" ]; then
echo "Packages installed in /:"
else
echo "Packages installed in $target:"
fi
awk -F/ '{
printf "\t%-20s\t(%s)\n", $NF, $0
}' $target/.installed
fi
shift
;;
-i|--info|--what*|--where*)
if [ -z "$2" ]; then
echo "--info requires an argument" 1>&2
exit 1
fi
$ZCAT $target/.map | egrep $2 | awk '
BEGIN {
done=0
last_path=""
}
$3 != last_path {
print $3
if ($4 != "0")
print "\tVersion", $4
last_path = $3
done=0
}
done == 0 && $1 == "COPY" { print "\tcopy of", $2 }
done == 0 && $1 == "COPYNEW" { print "\tbased on", $2 }
done == 0 && $1 == "LINK" { print "\tlink to", $2 }
done == 0 && $1 == "SLINK" { print "\tsymlink to", $2 }
done == 0 { done=1 }
'
shift; shift
;;
-r|--rebuild)
if [ ! -f $target/.installed ]; then
echo "No packages installed in $target."
echo "Use --add to add a package."
exit 1
fi
[ -z "$quiet" ] && echo $use_escapes "Merging package maps:\n\t\c"
rm -f $target/.map.old
[ -f $target/.map ] && mv $target/.map $target/.map.old
while read i
do
[ -z "$quiet" ] && echo $use_escapes "`basename $i` \c" 1>&2
gen_list $i
done < $target/.installed | sort -b -r +2 | $COMP > $target/.map
[ -z "$quiet" ] && echo
[ -z "$quiet" ] && echo
if [ -f $target/.map.old ]; then
[ -z "$quiet" ] && echo "Removing obsolete files:"
$ZCAT $target/.map | awk '!/^COPYNEW/ { print $3 }' | sort | uniq > /tmp/pkg$$
$ZCAT $target/.map.old | awk '!/^COPYNEW/ { print $3 }' | sort | uniq | comm -13 /tmp/pkg$$ - | /usr/lib/pkg/pipe-rm $no_action $target
rm -f /tmp/pkg$$
fi
[ -z "$quiet" ] && echo $use_escapes "\nRunning pre-install scripts:\n\t\c"
while read i
do
[ -z "$quiet" ] && echo $use_escapes "`basename $i` \c" 1>&2
if [ -r $i/PKG/pre-install ]; then
(cd $i; sh ./PKG/pre-install $no_action $target < /dev/tty > /dev/tty 2>&1)
fi
done < $target/.installed
[ -z "$quiet" ] && echo
[ -z "$quiet" ] && echo $use_escapes "\nBuilding target structure..."
do_install $target
[ -z "$quiet" ] && echo $use_escapes "\nRunning post-install scripts:\n\t\c"
while read i
do
[ -z "$quiet" ] && echo $use_escapes "`basename $i` \c" 1>&2
if [ -r $i/PKG/post-install ]; then
(cd $i; sh ./PKG/post-install $no_action $target < /dev/tty > /dev/tty 2>&1)
fi
done < $target/.installed
[ -z "$quiet" ] && echo
if [ -n "$no_action" -a -f $target/.map.old ]; then
rm -f $target/.map
mv $target/.map.old $target/.map
else
rm -f $target/.map.old
fi
if [ -z "$no_action" -a -x /usr/lib/pkg/prepare ]; then
/usr/lib/pkg/prepare $target
fi
shift
;;
*)
echo "${progname}: unrecognised option \`$1'"
echo "run ${progname} with no arguments for help"
exit 1
;;
esac
done
# If the .installed file is newer than the .map file (if any) then we will
# need to rebuild the structure at some stage.
if [ -z "$quiet" -a -f $target/.installed ]; then
if [ ! -f $target/.map -o $target/.installed -nt $target/.map ]; then
echo "The target structure may not represent currently installed packages."
echo "Use --rebuild to rebuild the target structure."
fi
fi